{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Red Team KubeHound Workflow\n",
    "\n",
    "A step by step example workflow of how to use KubeHound for Red Team operations."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Initial Setup\n",
    "\n",
    "Connection is being initated directly from the docker using the env vars `GRAPH_NOTEBOOK_HOST` and `GRAPH_NOTEBOOK_PORT`. To overwrite it you can use the magic `%%graph_notebook_config` [details here](https://github.com/aws/graph-notebook/tree/main/additional-databases/gremlin-server#connecting-to-a-local-gremlin-server-from-jupyter).\n",
    "\n",
    "Now set the appearance customizations for the notebook. You can see a guide on possible options [here](https://github.com/aws/graph-notebook/blob/623d43827f798c33125219e8f45ad1b6e5b29513/src/graph_notebook/notebooks/01-Neptune-Database/02-Visualization/Grouping-and-Appearance-Customization-Gremlin.ipynb#L680)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "init_cell": true
   },
   "outputs": [],
   "source": [
    "%%capture \"Remove this line to see debug information\"\n",
    "%%graph_notebook_vis_options\n",
    "{\n",
    "  \"edges\": {\n",
    "    \"smooth\": {\n",
    "      \"enabled\": true,\n",
    "      \"type\": \"dynamic\"\n",
    "    },\n",
    "    \"arrows\": {\n",
    "      \"to\": {\n",
    "        \"enabled\": true,\n",
    "        \"type\": \"arrow\"\n",
    "      }\n",
    "    }\n",
    "  }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Worfklow"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Initial Recon\n",
    "\n",
    "Look for exposed endpoints attached to containers and return the port details and image. This enables us to match against any exploits in our catalogue"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%gremlin\n",
    "kh.endpoints()\n",
    "\t.has(\"runID\", graph.variables().get('runID_yourid').get())\n",
    "\t.where(out().hasLabel(\"Container\"))\n",
    "\t.project('port',\"portName\", 'image')\n",
    "\t.by(values(\"port\"))\n",
    "\t.by(values(\"portName\"))\n",
    "\t.by(out().hasLabel(\"Container\").values(\"image\"))\n",
    "\t.dedup()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now let's focus on those with a critical attack path"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%gremlin\n",
    "kh.endpoints()\n",
    "\t.has(\"runID\", graph.variables().get('runID_yourid').get())\n",
    "\t.hasCriticalPath()\n",
    "\t.where(out().hasLabel(\"Container\"))\n",
    "\t.project('port',\"portName\", 'image')\n",
    "\t.by(values(\"port\"))\n",
    "\t.by(values(\"portName\"))\n",
    "\t.by(out().hasLabel(\"Container\").values(\"image\"))\n",
    "\t.dedup()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Attack Path Analysis\n",
    "\n",
    "Let's pick a promising target we have an exploit for and look at possible attack paths"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%gremlin -d class -g critical -le 50 -p inv,oute\n",
    "kh.endpoints()\n",
    "\t.has(\"runID\", graph.variables().get('runID_yourid').get())\n",
    "\t.has(\"portName\", \"elasticsearch\")\t// Change the value here for those found\n",
    "\t.not(has(\"protocol\", \"UDP\")) \t\t// Exclude or change based on requirements\n",
    "\t.criticalPaths()\n",
    "\t.by(elementMap())\n",
    "\t.limit(100)\t\t\t\t\t\t\t// Limit the number of results for large clusters"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now to refine our analysis, let's discount a few of the noisier attacks and focus on shorter attack paths. See [reference documentation](https://kubehound.io/reference/attacks/) for detaills of these attacks."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%gremlin -d class -g critical -le 50 -p inv,oute\n",
    "kh.endpoints()\n",
    "\t.has(\"runID\", graph.variables().get('runID_yourid').get())\n",
    "\t.has(\"portName\", \"elasticsearch\")  // Change the value here for those found\n",
    "\t.criticalPathsFilter(6, \"TOKEN_BRUTEFORCE\", \"POD_EXEC\", \"POD_CREATE\")\n",
    "\t.by(elementMap())\n",
    "    .limit(100)\t// Limit the number of results for large clusters"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now let's explore a couple of interesting endpoints which do not have a critical path BUT get us to a Node which could contain useful resources outside the scope of KubeHound e.g AWS credentials, SSH keys, etc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%gremlin -d name -g class -le 50 -p inv,oute\n",
    "kh.endpoints()\n",
    "\t.has(\"runID\", graph.variables().get('runID_yourid').get())\n",
    "\t.has(\"portName\", within(\"jmx\", \"ssh\", \"log4j\")) // Change the values here for those found\n",
    "\t.repeat(\n",
    "\t\toutE().inV()\n",
    "\t\t.simplePath())\n",
    "\t.until(\n",
    "\t\thasLabel(\"Node\")\n",
    "\t\t.or()\n",
    "\t\t.loops().is(5))\n",
    "\t.hasLabel(\"Node\")\n",
    "\t.path()\n",
    "\t.by(elementMap())\n",
    "    .limit(100)\t// Limit the number of results for large clusters"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
